package com.icoolkj.ms.auth.service.impl;

import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.generator.CodeGenerator;
import com.icoolkj.ms.api.auth.dto.CaptchaDTO;
import com.icoolkj.ms.api.auth.vo.CaptchaVO;
import com.icoolkj.ms.auth.enums.CaptchaType;
import com.icoolkj.ms.auth.properties.CaptchaProperties;
import com.icoolkj.ms.auth.service.IAuthStrategy;
import com.icoolkj.ms.common.cache.utils.RedisUtil;
import com.icoolkj.ms.common.core.constant.CommonConstants;
import com.icoolkj.ms.common.core.constant.GlobalConstants;
import com.icoolkj.ms.common.core.response.ServerResponseEntity;
import com.icoolkj.ms.common.core.utils.SpringContextUtils;
import com.icoolkj.ms.common.core.utils.reflect.ReflectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.stereotype.Service;

/**
 * @author icoolkj
 * @version 1.0
 * @description
 * @createDate 2025/02/24 10:57
 */
@Service("uuid" + IAuthStrategy.BASE_AUTH_STRATEGY)
public class AuthStrategyUuidImpl extends AbstractAuthStrategy {

    @Autowired
    private CaptchaProperties captchaProperties;

    @Override
    public boolean validateCode(CaptchaDTO captchaDTO) {
        return doValidateCode(captchaDTO.getUuid(), "uuid", captchaDTO);
    }

    /**
     * 生成验证码
     * @param captchaKey 生成验证码KEY
     * @return 验证结果
     */
    @Override
    public ServerResponseEntity generateCaptcha(String captchaKey) {
        CaptchaVO captchaVo = new CaptchaVO();
        boolean captchaEnabled = captchaProperties.getEnabled();
        if (!captchaEnabled) {
            captchaVo.setCaptchaEnabled(false);
            return ServerResponseEntity.success(captchaVo);
        }

        String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + captchaKey;
        // 生成验证码
        CaptchaType captchaType = captchaProperties.getType();
        boolean isMath = CaptchaType.MATH == captchaType;
        Integer length = isMath ? captchaProperties.getNumberLength() : captchaProperties.getCharLength();
        CodeGenerator codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), length);
        AbstractCaptcha captcha = SpringContextUtils.getBean(captchaProperties.getCategory().getClazz());
        captcha.setGenerator(codeGenerator);
        captcha.createCode();
        // 如果是数学验证码，使用SpEL表达式处理验证码结果
        String code = captcha.getCode();
        if (isMath) {
            ExpressionParser parser = new SpelExpressionParser();
            Expression exp = parser.parseExpression(StringUtils.remove(code, "="));
            code = exp.getValue(String.class);
        }
        RedisUtil.set(verifyKey, code, CommonConstants.CAPTCHA_EXPIRATION);
        captchaVo.setUuid(captchaKey);
        captchaVo.setImg(captcha.getImageBase64());
        return ServerResponseEntity.success(captchaVo);
    }
}
